package com.huifer.wgx.service.impl;

import com.huifer.wgx.model.FieldPointEntity;
import com.huifer.wgx.model.InteriorPointEntity;
import com.huifer.wgx.model.RtkPointEntity;
import com.huifer.wgx.repository.FieldPointRepository;
import com.huifer.wgx.repository.InteriorPointRepository;
import com.huifer.wgx.repository.RtkPointRepository;
import com.huifer.wgx.service.InterPointService;
import com.huifer.wgx.spec.PointLineTypeSpec;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

/**
 * <p>Title : InterPointServiceImpl </p>
 * <p>Description : </p>
 *
 * @author huifer
 * @date 2019-03-21
 */
@Service
public class InterPointServiceImpl implements InterPointService {

    @Autowired
    private FieldPointRepository fieldPointRepository;
    @Autowired
    private InteriorPointRepository interiorPointRepository;
    @Autowired
    private RtkPointRepository rtkPointRepository;

    /**
     * 将外业点转换成内业点
     *
     * @param workId 工作id
     * @param personnelId 内业人员id
     * @return 内业点
     */
    @Override
    public List<InteriorPointEntity> field2InterPoint(Long workId, Long personnelId) {
        Specification<FieldPointEntity> spec = (Specification<FieldPointEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                .and(
                        criteriaBuilder.equal(root.get("workId"), workId)
                );
        List<FieldPointEntity> fieldPointRepositoryAll = fieldPointRepository.findAll(spec);
        List<InteriorPointEntity> interiorPointEntities = field2InterPointStac(
                fieldPointRepositoryAll,
                personnelId);
        try {
            return interiorPointRepository.saveAll(interiorPointEntities);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 外业点列表转换内业点
     *
     * @param fieldPointRepositoryAll 外业点列表
     * @param personnelId 内业点
     * @return 内业点列表
     */
    private List<InteriorPointEntity> field2InterPointStac(
            List<FieldPointEntity> fieldPointRepositoryAll, Long personnelId) {
        try {

            List<InteriorPointEntity> result = new ArrayList<>();

            for (int i = 0; i < fieldPointRepositoryAll.size(); i++) {
                FieldPointEntity out = fieldPointRepositoryAll.get(i);
                Specification<RtkPointEntity> specification = (Specification<RtkPointEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                        .equal(root.get("rtkId"), out.getRtkId());

                RtkPointEntity rtkPointEntity = rtkPointRepository.findAll(specification)
                        .get(rtkPointRepository.findAll(specification).size() - 1);

                InteriorPointEntity inPoint = new InteriorPointEntity();

                inPoint.setInteriorPointName(out.getFieldPointName());
                inPoint.setInteriorPointManholeCoverType(out.getFieldPointManholeCoverType());
                inPoint.setInteriorPointIsmesh(out.getFieldPointIsmesh());
                inPoint.setInteriorPointDeep(out.getFieldPointDeep());
                inPoint.setInteriorPointSize(out.getFieldPointSize());

                inPoint.setPointType(PointLineTypeSpec.pointType(out.getFieldPointName()).getDesc());

                // 坐标
                inPoint.setInteriorPointX(rtkPointEntity.getRtkX());
                inPoint.setInteriorPointY(rtkPointEntity.getRtkY());
                inPoint.setInteriorPointZ(rtkPointEntity.getRtkZ());
                // 关联关系
                inPoint.setWorkId(out.getWorkId());
                inPoint.setPersonnelId(personnelId);

                result.add(inPoint);
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 保存内业点
     *
     * @param iPoint 内业点
     * @return 内业点
     */
    @Override
    public InteriorPointEntity saveOne(InteriorPointEntity iPoint) {
        try {
            return interiorPointRepository.save(iPoint);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 跟新内业点
     *
     * @param iPoint 内业点
     * @return 内业点
     */
    @Override
    public InteriorPointEntity updateIpoint(InteriorPointEntity iPoint) {
        try {
            return interiorPointRepository.save(iPoint);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 查询所有
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @return 内业点
     */
    @Override
    public Page<InteriorPointEntity> findAll(Integer pageNum, Integer pageSize) {

        return getInteriorPointEntity(pageNum, pageSize, null);
    }

    /**
     * 根据工程id查询所有
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @param workId 工程id
     * @return 内业点结果
     */
    @Override
    public Page<InteriorPointEntity> findByWorkId(Integer pageNum, Integer pageSize, Long workId) {
        Specification<InteriorPointEntity> spec = (Specification<InteriorPointEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                .equal(root.get("workId"), workId);

        return getInteriorPointEntity(pageNum, pageSize, spec);
    }

    /**
     * 根据内业人员id查询所有
     *
     * @param personnelId 采集人id
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @return 内业点结果
     */
    @Override
    public Page<InteriorPointEntity> findByPersonnelId(Long personnelId, Integer pageNum,
            Integer pageSize) {
        Specification<InteriorPointEntity> spec = (Specification<InteriorPointEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                .equal(root.get("personnelId"), personnelId);

        return getInteriorPointEntity(pageNum, pageSize, spec);
    }

    /**
     * 获取全部内业点
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @param spec 条件
     * @return 内业点
     */
    private Page<InteriorPointEntity> getInteriorPointEntity(Integer pageNum, Integer pageSize,
            Specification<InteriorPointEntity> spec) {
        Sort sort = new Sort(Direction.DESC, "interiorPointId");
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize, sort);
        return interiorPointRepository.findAll(spec, pageable);
    }
}
